export default class Socket {
  constructor({
    url = "wss://172.24.4.35:10096",
    heartTime = 30000,
    heartMsg = "heartBeat",
    isReconnect = true,
    reconnectTime = 5000,
    reconnectCount = -1,
    openCb = null,
    closeCb = null,
    messageCb = null,
    errorCb = null,
  } = {}) {
    this.socketTask = null; // ws对象
    this.url = url; // 链接的通道的地址
    this.heartTime = heartTime; // 心跳时间间隔,默认为30000
    this.heartMsg = heartMsg; // 心跳信息,默认为'heartBeat'
    this.isReconnect = isReconnect; // 是否自动重连,默认为true
    this.reconnectTime = reconnectTime; // 重连时间间隔,默认 5000
    this.reconnectCount = reconnectCount; // 重连次数 -1 则不限制,默认为-1
    this.heartTimer = 0; // 心跳计时器
    this.reconnectTimer = 0; // 重连计时器
    this.openCb = openCb; // 连接成功的回调
    this.closeCb = closeCb; // 关闭的回调
    this.messageCb = messageCb; // 消息的回调
    this.errorCb = errorCb; // 错误的回调
  }

  isConnectSucc = false; // 是否连接成功

  // 链接
  connection() {
    const { url } = this;
    if (!url) {
      throw new Error("地址不存在，无法建立通道");
    }

    this.socketTask = uni.connectSocket({
      url,
      success: (res) => {
        this.isConnectSucc = true;
        console.log("WebSocket初始化成功");
      },
      fail: (rej) => {
        this.isConnectSucc = false;
        console.log("WebSocket初始化失败", rej);
      },
    });

    this.socketListener();
  }
  // 事件监听
  socketListener() {
    const { socketTask } = this;
    if (this.isConnectSucc) {
      try {
        socketTask.onOpen((event) => {
          console.log(
            "ws已连接---------------🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍",
            event
          );
          typeof this.openCb === "function" && this.openCb(event);
          this.heartReset();
        });
        socketTask.onMessage((event) => {
          typeof this.messageCb === "function" && this.messageCb(event);
          return;
          //以下逻辑暂时用不到
          if (event.data instanceof ArrayBuffer) {
            // 处理ArrayBuffer数据
            typeof this.messageCb === "function" && this.messageCb(event);
          } else {
            if (event.data == "音频播放结束") {
              return;
            }
            if (typeof event.data == "string") {
              //返回的语音转的文本
              this.messageCb(event);
            } else {
              const data = JSON.parse(event.data);
              switch (data.msgType) {
                case 1:
                  break;
                case 2: // 强制下线
                case 4: // 参数错误
                case 5: // 系统错误
                  uni.showToast({ title: data.data, icon: "none" });
                  this.close();
                  break;
                case 3: // 未能通过登录认证校验
                  uni.showToast({ title: data.data });
                  this.close();
                  break;
                default:
                  typeof this.messageCb === "function" && this.messageCb(event);
                  break;
              }
            }
          }
        });
        socketTask.onClose((event) => {
          console.log(
            "ws断了-----------------🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍🍍",
            JSON.stringify(event)
          );
          typeof this.closeCb === "function" && this.closeCb(event);
          clearInterval(this.heartTimer); // socket 关闭后清除心跳检测
        });
        socketTask.onError((event) => {
          typeof this.errorCb === "function" && this.errorCb(event);
          // this.reconnection();
        });
      } catch (error) {}
    }
  }
  // 发送消息
  sendMessage(message) {
    if (!this.isConnectSucc) return;
    try {
      const data = JSON.stringify(message);
      return new Promise((resolve, reject) => {
        this.socketTask.send({
          data,
          success() {
            console.log("json消息发送成功", data);
            resolve();
          },
          fail(error) {
            console.log(data);
            uni.showToast({
              title: "消息发送失败，请重试",
              icon: "none",
            });
            reject(error);
          },
        });
      });
    } catch (error) {
      throw new Error("sendMessage", error);
    }
  }

  sendBufferMessage(message) {
    if (!message) return;
    try {
      return new Promise((resolve, reject) => {
        this.socketTask.send({
          data: message,
          success() {
            resolve();
            // console.log("发送buffer成功");
          },
          fail(error) {
            console.log("消息二进制发送失败", error, message);
            // uni.showToast({
            //   title: "消息发送失败，请尝试重新进入页面",
            //   icon: "none",
            // });

            // reject(error);
          },
        });
      });
    } catch (error) {
      throw new Error("sendMessage", error);
    }
  }

  // 关闭
  close({ code = 1000, reason = "关闭" } = {}, cb) {
    try {
      this.socketTask.close({
        code,
        reason,
        success: () => {
          clearTimeout(this.heartTimer); // 清除心跳定时器
          clearTimeout(this.reconnectTimer); // 清除重连定时器
          this.isConnectSucc = false;
          this.isReconnect = false;
          this.socketTask && this.socketTask.close();
          console.log("关闭 WebSocket 成功");
          console.log(cb);
          cb && cb();
        },
        fail(err) {
          console.log("关闭 WebSocket 失败", err);
        },
      });
    } catch (error) {
      throw new Error("close", error);
    }
  }

  // 重连
  reconnection() {
    try {
      if (!this.isReconnect || this.reconnectCount === 0) {
        return;
      }
      this.isReconnect = false; // 避免重复连接
      this.reconnectTimer = setTimeout(() => {
        this.connection();
        this.isReconnect = true;
        if (this.reconnectCount !== -1) {
          this.reconnectCount--;
        }
      }, this.reconnectTime);
    } catch (error) {
      uni.showToast({
        icon: "none",
        title: "连接服务器失败，正在重试...",
      });
      throw new Error("reconnection", error);
    }
  }

  // 重置心跳
  heartReset() {
    clearInterval(this.heartTimer);
    this.heartStart();
  }

  // 心跳检测
  heartStart() {
    try {
      this.heartTimer = setInterval(() => {
        console.log("心跳检测");
        // this.socketTask && this.socketTask.send(JSON.stringify({ id: this.heartMsg }))
      }, this.heartTime);
    } catch (error) {
      throw new Error("heartStart", error);
    }
  }
}
